import { Object3D, PerspectiveCamera, Vector3 } from "three";
import { Point } from "../../Engine";
import Const from "../../application/constants/Const";
import Polyline from "./Polyline";
/**
 * 视椎体线框
 */
export default class FrustumLineFrame extends Object3D {
    private camera: PerspectiveCamera;
    private nearPlaneLine: Polyline;
    private farPlaneLine: Polyline;
    private lineColor: string;
    private cameraPoint: Point;

    /**
     * 视椎体线框
     * @param camera 相机
     * @param lineColor 线框的颜色
     * @example let lineColor = '#00FA9A'
       let virturalCamera = new PerspectiveCamera(45, 1, 1, 10000);
       this.lineObject = new FrustumLineFrame(virturalCamera);
       this.app.add(this.lineObject);
     */
    public constructor(camera: PerspectiveCamera, lineColor?:string){
        super();
        this.camera = camera;
        this['canNotSelect'] = true; //不参与射线拾取

        this.lineColor = (lineColor ? lineColor : '#00FA9A');
        this.position.copy(camera.position);
        this.cameraPoint = new Point(this.camera.position.x, this.camera.position.y, this.camera.position.z, Const.EPSGType.EPSGWeb);
        this.updateCameraMatrix();

         // 归一化坐标系中的八个顶点
         let normalizedVertices = [
            new Vector3(-1, -1, -1),  // 左下近
            new Vector3(1, -1, -1),   // 右下近
            new Vector3(1, 1, -1),    // 右上近
            new Vector3(-1, 1, -1),   // 左上近

            new Vector3(-1, -1, 1),   // 左下远
            new Vector3(1, -1, 1),    // 右下远
            new Vector3(1, 1, 1),     // 右上远
            new Vector3(-1, 1, 1)     // 左上远
        ];

        let self = this;
        let nearPlanePointArray: Array<Point> = new Array<Point>();
        for(let i=0; i<4; i++){
            let normalizedVertex = normalizedVertices[i];
            let tempPoint = normalizedVertex.clone().unproject(self.camera);
            let point = new Point(tempPoint.x, tempPoint.y, tempPoint.z, Const.EPSGType.EPSGWeb);
            nearPlanePointArray.push(point);
        }
        nearPlanePointArray.push(nearPlanePointArray[0].clone());
        let nearPlaneLineData = {
            pointArray: nearPlanePointArray,  //多边形的顶点数组
            color: this.lineColor,
            lineWidth: 2,  //线的宽度
            depthTest: true
        };
        this.nearPlaneLine = new Polyline(nearPlaneLineData);
        let nearPlaneLinePosition = this.nearPlaneLine.position.clone().sub(this.position);
        this.nearPlaneLine.position.copy(nearPlaneLinePosition);
        this.add(this.nearPlaneLine);

        let farPlanePointArray: Array<Point> = new Array<Point>();
        for(let i=4; i<normalizedVertices.length; i++){
            let normalizedVertex = normalizedVertices[i];
            let tempPoint = normalizedVertex.clone().unproject(self.camera);
            let point = new Point(tempPoint.x, tempPoint.y, tempPoint.z, Const.EPSGType.EPSGWeb);
            farPlanePointArray.push(point);
        }
        farPlanePointArray.push(farPlanePointArray[0].clone());
        let farPlaneLineData = {
            pointArray: farPlanePointArray,  //多边形的顶点数组
            color: this.lineColor,
            lineWidth: 2,  //线的宽度
            depthTest: true
        };
        this.farPlaneLine = new Polyline(farPlaneLineData);
        let farPlaneLinePosition = this.farPlaneLine.position.clone().sub(this.position);
        this.farPlaneLine.position.copy(farPlaneLinePosition);
        this.add(this.farPlaneLine);

        this.buildSlopeLine(normalizedVertices[7]);
        this.buildSlopeLine(normalizedVertices[6]);
        this.buildSlopeLine(normalizedVertices[5]);
        this.buildSlopeLine(normalizedVertices[4]);
    }

    private updateCameraMatrix(){
        this.camera.updateMatrix();
        this.camera.updateWorldMatrix(true, true);
        this.camera.updateMatrixWorld(true);
        this.camera.updateProjectionMatrix();
    }

    private buildSlopeLine(cornerNdcPoint){
        let pointArray: Array<Point> = new Array<Point>();
        let leftTopFarTempPoint = cornerNdcPoint.clone().unproject(this.camera);
        let leftTopFarPoint = new Point(leftTopFarTempPoint.x, leftTopFarTempPoint.y, leftTopFarTempPoint.z, Const.EPSGType.EPSGWeb);
        pointArray.push(leftTopFarPoint);
        pointArray.push(this.cameraPoint.clone());
        let slopeData = {
            pointArray: pointArray,  //多边形的顶点数组
            color: this.lineColor,
            lineWidth: 2,  //线的宽度
            depthTest: true
        };
        let slopLine = new Polyline(slopeData);
        let linePosition = slopLine.position.clone().sub(this.position);
        slopLine.position.copy(linePosition);
        this.add(slopLine);
    }
}
